package com.info.zhiduoduo.core.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.baomidou.mybatisplus.mapper.Condition;
import com.info.zhiduoduo.common.configs.DocConfig;
import com.info.zhiduoduo.common.configs.NotificationConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.crowdsource.CrowdsourceRegfromType;
import com.info.zhiduoduo.common.constants.entrustmentproject.AlipayPrincipalAccountFlowType;
import com.info.zhiduoduo.common.constants.entrustmentproject.EntrustProjectImportState;
import com.info.zhiduoduo.common.constants.entrustmentproject.EntrustProjectState;
import com.info.zhiduoduo.common.constants.entrustmentproject.EntrustState;
import com.info.zhiduoduo.common.constants.invoice.InvoiceType;
import com.info.zhiduoduo.common.constants.project.CalcAmountType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.excelconverter.ZddReadListener;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.MapUtil;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.formbean.CalcProjectChargesFormBean;
import com.info.zhiduoduo.core.formbean.crowdsource.AddCrowdsourceModel;
import com.info.zhiduoduo.core.formbean.entrustmentproject.ImportRawBean;
import com.info.zhiduoduo.core.service.*;
import com.info.zhiduoduo.core.vo.entrustmentproject.ImportResultVO;
import com.info.zhiduoduo.repository.dto.crowdsource.CalcCrowdsourceItemAmountModel;
import com.info.zhiduoduo.repository.dto.crowdsource.CrowdsourceItemAmountCalcResult;
import com.info.zhiduoduo.repository.dto.entrustmentproject.EntrustmentProjectItemDto;
import com.info.zhiduoduo.repository.dto.entrustmentproject.EntrustmentProjectItemImportDto;
import com.info.zhiduoduo.repository.dto.maker.MakerAlipayDto;
import com.info.zhiduoduo.repository.dto.maker.MakerDetailDto;
import com.info.zhiduoduo.repository.dto.project.CalcProjectChargesDto;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.company.CompanyAccount;
import com.info.zhiduoduo.repository.entity.crowdsource.Crowdsource;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceAccount;
import com.info.zhiduoduo.repository.entity.quota.CrowdsourceCityQuota;
import com.info.zhiduoduo.repository.entity.entrustmentproject.EntrustmentProject;
import com.info.zhiduoduo.repository.entity.entrustmentproject.EntrustmentProjectItem;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayPrincipal;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayPrincipalFlow;
import com.info.zhiduoduo.repository.entity.system.SystemProjectcategory;
import com.info.zhiduoduo.repository.mapper.company.CompanyAccountMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyMapper;
import com.info.zhiduoduo.repository.mapper.crowdsource.CrowdsourceAccountMapper;
import com.info.zhiduoduo.repository.mapper.entrustmentproject.EntrustmentProjectItemMapper;
import com.info.zhiduoduo.repository.mapper.entrustmentproject.EntrustmentProjectMapper;
import com.info.zhiduoduo.repository.mapper.maker.*;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CoreEntrustProjectServiceImpl implements CoreEntrustProjectServcie {

	@Autowired
	CoreCrowdsourceService coreCrowdsourceService;
	@Autowired
	CoreEntrustProjectServcie coreEntrustProjectServcie;
	@Autowired
	CoreInvoiceService coreInvoiceService;
	@Autowired
	CoreMakerAlipayService coreMakerAlipayService;
	@Autowired
	CoreProjectService coreProjectService;
	@Autowired
	CrowdsourceProjectService crowdsourceProjectService;
	@Autowired
	CoreBrokerageService coreBrokerageService;

	@Resource
	EntrustmentProjectMapper entrustmentProjectMapper;
	@Resource
	CrowdsourceAccountMapper crowdsourceAccountMapper;
	@Resource
	EntrustmentProjectItemMapper entrustmentProjectItemMapper;
	@Resource
	MakerAlipayPrincipalMapper makerAlipayPrincipalMapper;
	@Resource
	MakerAlipayAgreementMapper makerAlipayAgreementMapper;
	@Resource
	MakerAlipayAccountBookMapper makerAlipayAccountBookMapper;
	@Resource
	CompanyMapper companyMapper;
	@Resource
	MakerAlipayMapper makerAlipayMapper;
	@Resource
	MakerMapper makerMapper;
	@Resource
	CompanyAccountMapper companyAccountMapper;

	@Autowired
	DocConfig docConfig;

	@Autowired
	CommonService commonService;
	@Resource
	WxMessageService wxMessageService;

	@Autowired
	NotificationConfig notificationConfig;

	private ExecutorService executor = Executors.newSingleThreadExecutor();

	@Override
	public void refreshProjectStatus(int importId) {
		EntrustmentProject entrustmentProject = new EntrustmentProject().selectById(importId);
		if (entrustmentProject == null) return;
		List<EntrustmentProjectItem> itemList = entrustmentProjectItemMapper.listItems(importId);
		int projectDealingCount = 0;
		int projectCompleteCount = 0;
		int projectFailCount = 0;
		BigDecimal projectCompleteAmount = BigDecimal.ZERO;
		BigDecimal projectFailAmount = BigDecimal.ZERO;
		for (EntrustmentProjectItem item : itemList) {
			Integer state = item.getState();
			if (NumberUtil.equals(state, EntrustProjectState.DISPATCHED)) {
				projectDealingCount++;
			} else if (NumberUtil.equals(state, EntrustProjectState.FINISH)) {
				projectCompleteCount++;
				projectCompleteAmount = projectCompleteAmount.add(item.getAmount());
			} else if (NumberUtil.equals(state, EntrustProjectState.FAIL)) {
				projectFailCount++;
				projectFailAmount = projectFailAmount.add(item.getAmount());
			}
		}
		int state = entrustmentProject.getState();
		Integer importedItemCount = entrustmentProject.getImportedItemCount();
		if (projectCompleteCount == importedItemCount) {
			state = EntrustProjectImportState.FULL_COMPLETE;

			// 全部完成,创客团项目处理合伙人佣金结算.
			if (!NumberUtil.equals(entrustmentProject.getState(), EntrustProjectImportState.FULL_COMPLETE)) {
				if (NumberUtil.equals(ProjectType.MAKER_GROUPON_ZHIDUODUO, entrustmentProject.getProjectType())) {
					coreBrokerageService.handleMakerGrouponZhiduoduoProjectPartnerBrokerage(entrustmentProject);
				} else if (NumberUtil.equals(ProjectType.MAKER_GROUPON_CROWDSOURCE, entrustmentProject.getProjectType())) {
					coreBrokerageService.handleMakerGrouponCrowdsourceProjectPartnerBrokerage(entrustmentProject);
				}
			}
		} else if (projectCompleteCount > 0) {
			state = EntrustProjectImportState.PART_COMPLETE;
		} else if (projectDealingCount > 0) {
			state = EntrustProjectImportState.DEALING;
		} else if (projectFailCount == importedItemCount) {
			// 全部失败，变成处理中, 可以重新支付
			state = EntrustProjectImportState.DEALING;
		}
		entrustmentProject.setProjectDealingCount(projectDealingCount)
				.setProjectCompleteCount(projectCompleteCount)
				.setProjectCompleteAmount(projectCompleteAmount)
				.setProjectFailCount(projectFailCount)
				.setProjectFailAmount(projectFailAmount)
				.setState(state)
				.updateById();
	}

	@Override
	public void processProjectPrincipalTransfer2Trustee(List<EntrustmentProjectItem> list) {
		// 将项目按照委托人principalId进行分组
		Map<Integer, List<EntrustmentProjectItem>> map = list.stream()
				.collect(Collectors.groupingBy(EntrustmentProjectItem::getPrincipalId));
		for (Integer principalId : map.keySet()) {
			// 判断委托人主体账户总金额是否足够
			MakerAlipayPrincipal alipayPrincipal = coreMakerAlipayService.queryZddPrincipalAccount(principalId);
			BigDecimal availableAmount = alipayPrincipal.getAvailableAmount();
			BigDecimal frozenAmount = alipayPrincipal.getFrozenAmount();
			BigDecimal realAvailableAmount = availableAmount.subtract(frozenAmount);
			BigDecimal totalAmount = list.stream().map(EntrustmentProjectItem::getAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
			// 冻结机制有问题，先不判断冻结金额
			// if (realAvailableAmount.compareTo(totalAmount) < 0) {
			// 	throw SmartException.of(StatusMsg.StatusMsg_239, principalId);
			// }
			if (availableAmount.compareTo(totalAmount) < 0) {
				throw SmartException.of(StatusMsg.StatusMsg_238, principalId);
			}

			// 先冻结委托人主体记账本的金额,冻结金额为totalAmount
			BigDecimal prevFrozenAmount = alipayPrincipal.getFrozenAmount();
			if (makerAlipayPrincipalMapper.frozen(principalId, totalAmount)) {
				// 重新查冻结余额
				BigDecimal afterFrozenAmount = new MakerAlipayPrincipal().selectById(principalId).getFrozenAmount();
				MakerAlipayPrincipalFlow principalFlow = new MakerAlipayPrincipalFlow().setOrderNo(RandomUtil.createRandomNo("FROZEN_",
								""))
						.setPrincipalId(principalId)
						.setAccountBookId(alipayPrincipal.getAccountBookId())
						.setType(AlipayPrincipalAccountFlowType.FROZEN)
						.setAmount(totalAmount)
						.setPrevAmount(alipayPrincipal.getAvailableAmount())
						.setAfterAmount(alipayPrincipal.getAvailableAmount())
						.setPrevFrozenAmount(prevFrozenAmount)
						.setAfterFrozenAmount(afterFrozenAmount)
						.setRemark("发布项目,冻结金额");
				principalFlow.insert();
			} else {
				throw SmartException.of(StatusMsg.StatusMsg_239);
			}
		}

		// 更新状态
		Date now = new Date();
		for (EntrustmentProjectItem item : list) {
			item.setDispatchTime(now).setState(EntrustProjectState.DISPATCHED).setEntrustState(EntrustState.DISPATCHED).updateById();
			coreEntrustProjectServcie.refreshProjectStatus(item.getImportId());
		}
		// 异步执行转账操作, 因为这是比较耗时的.
		processTransfer2Entrustee(list);
	}

	private List<ImportRawBean> parseImportFile(MultipartFile file, EntrustmentProject entrustmentProject, int projectType)
			throws Exception {
		List<ImportRawBean> beanList = Lists.newArrayList();
		EasyExcel.read(file.getInputStream()).registerReadListener(new ZddReadListener<Map<Integer, String>>() {
			@Override
			public void invoke(Map<Integer, String> map, AnalysisContext context) {
				ReadRowHolder rowHolder = context.readRowHolder();
				Integer rowIndex = rowHolder.getRowIndex();
				if (rowIndex == 3) {
					// 企业名称行
					entrustmentProject.setCompname(map.get(1));
					// 项目备注
					entrustmentProject.setRemark(map.get(4));
				} else if (rowIndex >= 6) {
					// 空数据行, 继续执行下一行
					if (MapUtil.isAllValueEmpty(map)) return;
					// 数据行
					ImportRawBean bean = null;
					if (ProjectType.isEntrustProject(projectType)) {
						bean = ImportRawBean.ofEntrustItem(map);
					} else if (ProjectType.isMakerGrouponProject(projectType)) {
						bean = ImportRawBean.ofMakerGrouponItem(map);
					}
					beanList.add(bean);
				}
			}
		}).ignoreEmptyRow(true).sheet(0).autoTrim(true).doRead();
		return beanList;
	}

	private void processTransfer2Entrustee(List<EntrustmentProjectItem> list) {
		// 第一层按principalId 分组, 第二层再按userid分组
		Map<Integer, Map<Integer, List<EntrustmentProjectItem>>> map = list.stream()
				.collect(Collectors.groupingBy(EntrustmentProjectItem::getPrincipalId,
						Collectors.groupingBy(EntrustmentProjectItem::getEntrusteeId)));
		executor.submit(() -> {
			for (Integer principalId : map.keySet()) {
				Map<Integer, List<EntrustmentProjectItem>> userItemMap = map.get(principalId);
				for (Integer userid : userItemMap.keySet()) {
					List<EntrustmentProjectItem> userItemList = userItemMap.get(userid);
					// 统计每个受托人需要的总金额, 然后给每个创客转账
					BigDecimal userAmount = userItemList.stream()
							.map(EntrustmentProjectItem::getAmount)
							.reduce(BigDecimal::add)
							.orElse(BigDecimal.ZERO);
					AlipayFundTransUniTransferResponse response = coreMakerAlipayService.transfer2Entrustee(principalId, userid,
							userAmount, userItemList.get(0).getId(), list.get(0).getProjectType());
					if (response == null || !response.isSuccess()) {
						// 失败， 解冻金额， 并记录失败原因
						coreMakerAlipayService.unfrozonPrincipalAmount(principalId, userAmount);
						for (EntrustmentProjectItem item : userItemList) {
							if (response != null) {
								item.setAlipayErrorCode(response.getSubCode()).setAlipayErrorMsg(response.getSubMsg());
							}
							item.setState(EntrustProjectState.FAIL).setFinishTime(new Date()).updateById();
							coreEntrustProjectServcie.refreshProjectStatus(item.getImportId());
						}
						//委托接单项目发送失败通知
						log.info("委托发单, processTransfer2Entrustee,发起转账response 不成功, 解冻被冻结的余额, subCode={}, subMsg:{}",
								response == null ? "" : response.getSubMsg(), response == null ? "" : response.getSubMsg());
						coreEntrustProjectServcie.handleTransferFailed(userItemList.get(0).getId());
					} else {
						// 成功
						String orderNo = response.getOutBizNo();
						for (EntrustmentProjectItem item : userItemList) {
							item.setTransferNo(orderNo).setEntrustState(EntrustState.TRANSFERED).setTransferTime(new Date()).updateById();
						}
					}
				}
				if (ProjectType.isCrowdsourceProject(list.get(0).getProjectType())) {
					// 委托接单-智众包项目 开项目发票, 委托主体开给发单企业
					coreInvoiceService.createEntrustCrowdsourceProjectInvoice(list);
				}
			}
		});
	}

	private void handleCrowdsourceAccount(Map<String, Integer> bindcompMap, Integer bindcompid, EntrustmentProjectItem item) {
		CrowdsourceAccount crowdsourceAccount = crowdsourceAccountMapper.findByIdno(item.getPayeeIdNo(), item.getPayeeName());
		if (crowdsourceAccount == null) {
			int regfrom = CrowdsourceRegfromType.ENTRUSTMENT_PROJECT;
			if (ProjectType.isEntrustProject(item.getProjectType())) {
				regfrom = CrowdsourceRegfromType.MAKERGROUP_PROJECT;
			}
			AddCrowdsourceModel model = new AddCrowdsourceModel().setIdno(item.getPayeeIdNo())
					.setPhone(item.getPhone())
					.setRealname(item.getPayeeName())
					.setRegfrom(regfrom);

			// 智众包项目 自然人绑定的企业, 优先看导入的子项目上的Bindcompname, 没有则用受票方企业id
			if (StringUtil.isNotEmpty(item.getBindcompname())) {
				Integer nbindcompid = bindcompMap.computeIfAbsent(item.getBindcompname(), k -> {
					Company comp = companyMapper.getByCompname(k);
					return comp != null ? comp.getCompid() : null;
				});
				if (nbindcompid != null) bindcompid = nbindcompid;
			}
			item.setBindcompid(bindcompid);
			model.setBindcompid(bindcompid);

			if (item.getAccountType() == 2) {
				model.setAcctno(item.getAccountNo());
			} else if (item.getAccountType() == 1) {
				model.setAlipayLogonId(item.getAccountNo());
			}
			Crowdsource crowdsource = coreCrowdsourceService.addCrowdsource(model);
			item.setCrowdsourceid(crowdsource.getCrowdsourceid()).setCrowdsourceName(model.getRealname());
		} else {
			// 更新支付宝账号
			if (StringUtil.isEmpty(crowdsourceAccount.getAlipayLogonId()) && item.getAccountType() == 1) {
				crowdsourceAccount.setAlipayLogonId(item.getAccountNo()).updateById();
			}
			item.setCrowdsourceid(crowdsourceAccount.getCrowdsourceid()).setCrowdsourceName(crowdsourceAccount.getRealname());
		}
	}

	/**
	 * 计算每个子项目的税费
	 *
	 * @param item
	 * @param company
	 * @param serviceRate 委托接单项目需要手动指定服务费率，创客团项目不需要
	 * @param projectType
	 */
	@Override
	public void calculateItemAmount(EntrustmentProjectItem item, Company company, Double serviceRate, int projectType) {
		if (ProjectType.isEntrustProject(projectType)) {
			BigDecimal importAmount = item.getProjectAmount();
			BigDecimal taxInclusiveAmount = null;
			if (projectType == ProjectType.ENTRUST_CROWDSOURCE) {
				if (serviceRate == null) serviceRate = NumberUtil.safeDouble(company.getBaseTaxRate());
				taxInclusiveAmount = importAmount.multiply(BigDecimal.valueOf(1 + serviceRate));
			} else if (projectType == ProjectType.ENTRUST_ZHIDUODUO) {
				taxInclusiveAmount = importAmount.divide(BigDecimal.valueOf(1 - NumberUtil.safeDouble(serviceRate)), 4, RoundingMode.DOWN);
			}
			item.setAmount(importAmount);
			item.setServiceRate(serviceRate);
			item.setTaxInclusiveAmount(taxInclusiveAmount);
			item.setInvoiceAmount(taxInclusiveAmount);
			item.setDepositAmount(BigDecimal.ZERO);
			item.setCompanyPayAmount(taxInclusiveAmount);
		} else if (projectType == ProjectType.MAKER_GROUPON_ZHIDUODUO) {
			calcMakerGouponZhiduoduoAmount(item, CalcAmountType.ALL);
		} else if (projectType == ProjectType.MAKER_GROUPON_CROWDSOURCE) {
			calcMakerGroupCrowdsourceAmount(item, CalcAmountType.ALL);
		}
	}

	@Override
	public void calcProjectTotalAmount(EntrustmentProject entrustmentProject) {
		List<EntrustmentProjectItem> itemList = entrustmentProjectItemMapper.listItems(entrustmentProject.getId());
		calcProjectTotalAmount(entrustmentProject, itemList);
	}

	@Override
	public void calcProjectTotalAmount(EntrustmentProject entrustmentProject, List<EntrustmentProjectItem> itemList) {
		BigDecimal importedAmount = BigDecimal.ZERO;
		BigDecimal importedTaxInclusiveAmount = BigDecimal.ZERO;
		BigDecimal projectTotalPayableAmount = BigDecimal.ZERO;
		BigDecimal projectTotalInvoiceAmount = BigDecimal.ZERO;
		BigDecimal projectTotalReceiptAmount = BigDecimal.ZERO;
		BigDecimal depositTotalAmount = BigDecimal.ZERO;

		for (EntrustmentProjectItem item : itemList) {
			importedAmount = importedAmount.add(item.getProjectAmount());
			importedTaxInclusiveAmount = importedTaxInclusiveAmount.add(item.getTaxInclusiveAmount());
			projectTotalPayableAmount = projectTotalPayableAmount.add(item.getTaxInclusiveAmount());
			projectTotalInvoiceAmount = projectTotalInvoiceAmount.add(item.getInvoiceAmount());
			projectTotalReceiptAmount = projectTotalReceiptAmount.add(item.getAmount());
			depositTotalAmount = depositTotalAmount.add(item.getDepositAmount());

		}

		entrustmentProject.setImportedAmount(importedAmount)
				.setImportedTaxInclusiveAmount(importedTaxInclusiveAmount)
				.setProjectTotalPayableAmount(projectTotalPayableAmount)
				.setProjectTotalInvoiceAmount(projectTotalInvoiceAmount)
				.setProjectTotalReceiptAmount(projectTotalReceiptAmount)
				.setDepositTotalAmount(depositTotalAmount);
	}

	@Override
	public void calcMakerGouponZhiduoduoAmount(EntrustmentProjectItem item, int calcAmountType) {
		if (item == null) return;
		// 创客团, 项目的 企业应付金额就是导入的金额, 已经是含税金额
		BigDecimal taxInclusiveAmount = item.getProjectAmount();
		// 判断限额
		try {
			coreProjectService.checkMakerQuota(NumberUtil.safeInt(item.getCompid()), NumberUtil.safeInt(item.getEntrusteeId()),
					NumberUtil.safeInt(item.getId()), NumberUtil.safeInt(item.getProjectType()), taxInclusiveAmount, calcAmountType);
		} catch (SmartException e) {
			// 未通过限额检测，抛出报错，并将子项目数据返回
			throw e.setData(item);
		}
		// 计算税费服务费
		CalcProjectChargesDto calcProjectChargesDto = coreProjectService.calcProjectCharge(
				CalcProjectChargesFormBean.of(item, calcAmountType));
		BigDecimal serviceTaxAmount = calcProjectChargesDto.getServiceCharge().add(calcProjectChargesDto.getTaxFee());
		// 实发金额
		BigDecimal amount = taxInclusiveAmount.subtract(serviceTaxAmount);
		BigDecimal depositAmount = BigDecimal.ZERO;
		BigDecimal invoiceAmount = taxInclusiveAmount;
		BigDecimal companyPayAmount = taxInclusiveAmount;

		item.setAmount(amount)
				.setServiceCharge(calcProjectChargesDto.getServiceCharge())
				.setServiceRate(calcProjectChargesDto.getBaseServiceRatio())
				.setPartnerProjectServiceRate(calcProjectChargesDto.getPartnerProjectServiceRatio())
				.setTaxRate(calcProjectChargesDto.getTaxRatio())
				.setTaxFee(calcProjectChargesDto.getTaxFee())
				.setServiceTaxAmount(serviceTaxAmount)
				.setTaxInclusiveAmount(taxInclusiveAmount)
				.setDepositAmount(depositAmount)
				.setInvoiceAmount(invoiceAmount)
				.setCompanyPayAmount(companyPayAmount);
	}

	@Override
	public void calcMakerGroupCrowdsourceAmount(EntrustmentProjectItem item, int calcAmountType) {
		if (item == null) return;

		Integer compid = item.getCompid();
		Company company = new Company().selectById(compid);
		double partnerBrokerageRate = crowdsourceProjectService.getPartnerBrokerageRate(compid);
		CalcCrowdsourceItemAmountModel model = CalcCrowdsourceItemAmountModel.of(partnerBrokerageRate, company, item, calcAmountType);
		CrowdsourceItemAmountCalcResult calcResult = crowdsourceProjectService.calcItemAmount(model);

		// 创客工作室限额
		CrowdsourceCityQuota studioQuota = crowdsourceProjectService.findStudioCityQuota(item.getEntrusteeId());
		// 计算各个限额
		crowdsourceProjectService.handleProjectItemCalcQuota(company, calcResult, null, studioQuota);
		if (calcResult.getMakerExceedType() != 0 || calcResult.getMakerExceedPeriod() != 0) {
			// 表示众包创客限额超过了，过滤掉
			throw SmartException.of(StatusMsg.StatusMsg_614).setData(calcResult);
		}
		// 单笔限额
		if (calcResult.isSingleExceed()) throw SmartException.of(StatusMsg.StatusMsg_614).setData(calcResult);
		// 月度限额
		if (calcResult.isMonthlyExceed()) throw SmartException.of(StatusMsg.StatusMsg_614).setData(calcResult);
		// 季度限额
		if (calcResult.isQuarterlyExceed()) throw SmartException.of(StatusMsg.StatusMsg_614).setData(calcResult);
		// 年度限额
		if (calcResult.isYearlyExceed()) throw SmartException.of(StatusMsg.StatusMsg_614).setData(calcResult);

		BigDecimal taxInclusiveAmount = calcResult.getIntegratedTaxFee();
		BigDecimal depositAmount = calcResult.getDepositAmount();
		// 开票金额 = 综合税费 (不含保证金)
		BigDecimal invoiceAmount = taxInclusiveAmount;
		// 企业应付金额 = 含税金额(综合税费) + 保证金金额
		BigDecimal companyPayAmount = taxInclusiveAmount.add(depositAmount);
		item.setAmount(item.getProjectAmount())  // 实发金额 = 导入的项目金额
				.setTaxInclusiveAmount(taxInclusiveAmount)
				.setServiceTaxAmount(calcResult.getProjectServiceCharge())
				.setTaxFee(calcResult.getProjectServiceCharge())
				.setTaxRate(calcResult.getTaxRate())
				.setPartnerBrokerage(calcResult.getPartnerBrokerage())
				.setPartnerBrokerageRate(partnerBrokerageRate)
				.setDepositAmount(depositAmount)
				.setInvoiceAmount(invoiceAmount)
				.setCompanyPayAmount(companyPayAmount);
	}

	@Override
	public void handleTransferFailed(Integer projectItemId) {
		if(projectItemId == null || projectItemId == 0){
			log.error("委托发单支付失败发送通知失败");
			return;
		}
		//委托发单支付失败 通知riley,项目支付失败 通知给riley
		new Thread(() -> {
			EntrustmentProjectItem item = new EntrustmentProjectItem().selectById(projectItemId);
			if (item == null) {
				log.error("委托发单支付失败发送通知失败，子项目ID:{}", projectItemId);
			}
			String info = String.format("企业:%s,发布委托接单项目:%s 处理失败;%s(%s)", item.getCompname(), item.getName(), item.getCrowdsourceName(), item.getAlipayErrorMsg());
			commonService.sendEnterpriseWeChatNotice(notificationConfig.getRileyManagerId(), null, 1, info);
			wxMessageService.notifyAdminProjectPublishError(info);
		}).start();
	}
}
